/*!
    \copyright  Copyright (c) 2024 Qualcomm Technologies International, Ltd.
                All Rights Reserved.
                Qualcomm Technologies International, Ltd. Confidential and Proprietary.
    \file
    \defgroup   adkfs    AdkFS
    @{
        \ingroup    services
        \brief      Provides a common POSIX like API to interact with multiple Filesystem providers

        Where possible this API tries to follow POSIX file APIs.
        One notable difference is that the API will return the value of errno instead of setting a global "errno" variable.
*/

#ifndef ADKFS_H
#define ADKFS_H

#include "adkfs_types.h"

#include <stdint.h>
#include <stdio.h>

typedef enum adkfs_fseek_reference_t {
    /**
     *The starting point is zero or the beginning of the file.
     */
    ADKFS_SEEK_SET = 0,
    /**
     *The start point is the current value of the file pointer.
     */
    ADKFS_SEEK_CUR= 1,
    /**
     *The starting point is the current end-of-file position.
     */
    ADKFS_SEEK_END = 2,
} adkfs_fseek_reference_t;

#define ADKFS_SUCCESS(rc)    (rc == 0)

/**
 * \brief Open a file or create if does not exist. The latter depends on the access flags provided.
 *  
 * \param[out] handle: Handle to the file.
 * \param[in]  path: Absolute file path.
 * \param[in]  access: Type of access. \see adkfs_access_flags_t
 * \return
 *  0 -- Success
 *  Nonzero -- Failure \see errno.h for possible values and their meaning \see errno.h for possible values and their meaning
 */
int32_t AdkFs_Fopen(adkfs_fhandle_t *handle, const char *path, adkfs_access_flags_t access);

/**
 * \brief Get file size
 *
 * \param[in]  path: Absolute file path.
 * \param[out] fsize: Size of file in bytes.
 * 
 * \return
 *  0 -- Success
 *  Nonzero -- Failure \see errno.h for possible values and their meaning
 */
int32_t AdkFs_Fsize(const char *path, size_t *fsize);

/**
 * \brief Map a file into Data Memory for Read Only access
 *
 * Whether this allocates heap memory for the buffer or not
 * is platform dependent. On some platforms with low memory
 * this may map non-volatile storage into a readable memory window instead.
 * Any subsequent call to AdkFs_Fmap may invalidate a previous buffer returned by this API.
 * To free any possible resources allocated by this call, the caller
 * MUST call AdkFs_Funmap
 *
 * \param[in] handle: Handle to the file
 * \param[out] fbuffer: A pointer to the read-only Data memory buffer
 * 
 * \return
 *  0 -- Success
 *  Nonzero -- Failure \see errno.h for possible values and their meaning
 */
int32_t AdkFs_Fmap(adkfs_fhandle_t handle, const void **fbuffer);

/**
 * \brief Un-map a file from Data Memory
 *
 * This call releases a buffer obtained by a previous call to AdkFs_Fmap
 * and frees any resources that may be in use by it.
 * Any previous buffer provided by AdkFs_Fmap is invalidated after this call.
 * The file still needs to be closed by a call to AdkFs_Fclose.
 *
 * \param[in] handle: Handle to the file
 * 
 * \return
 *  0 -- Success
 *  Nonzero -- Failure \see errno.h for possible values and their meaning
 */
int32_t AdkFs_Funmap(adkfs_fhandle_t handle);

/**
 * \brief Move the file pointer for read/write to the required offset.
 *
 * \param[in] handle: Handle to the file.
 * \param[in] offset: The number of bytes to move the file pointer.
 * \param[in] ref: Refer to adkfs_fseek_reference_t for options.
 * 
 * \note The fseek() function shall allow the file-position indicator
 *      to be set beyond the end of existing data in the file.
 *      If data is later written at this point, subsequent reads 
 *      of data in the gap shall return bytes with the value 0x0 (or 0xFF for flash based storage)
 *      until data is actually written into the gap.
 * \return
 * 0 -- Success
 *  Nonzero -- Failure \see errno.h for possible values and their meaning
 */
int32_t AdkFs_Fseek(adkfs_fhandle_t handle, off_t offset, adkfs_fseek_reference_t ref);

/**
 * \brief Obtain the current value of the file-position indicator
 *
 * \param[in] handle: Handle to the file.
 * \param[out] offset: The value of the file-position indicator.
 * 
 * \return
 * 0 -- Success
 *  Nonzero -- Failure \see errno.h for possible values and their meaning
 */
int32_t AdkFs_Ftell(adkfs_fhandle_t handle, off_t *offset);

/**
 * \brief Read from file
 *
 * \param[in] handle: Handle to the file.
 * \param[in_out] buf_ptr: Buffer pointer to read data into.
 * \param[in] read_size: Data size to read from file.
 * \param[in_out] bytes_read: Actual data size read from file.
 *
 * \return
 * 0 -- Success
 *  Nonzero -- Failure \see errno.h for possible values and their meaning
 */
int32_t AdkFs_Fread(adkfs_fhandle_t handle, void *buf_ptr, size_t read_size, size_t *bytes_read);

/**
 * \brief Write to file
 * 
 * \param[in] handle: Handle to the file.
 * \param[in] buf_ptr: Buffer pointer to write data from.
 * \param[in] write_size: Data size to write into file.
 * \param[in_out] bytes_written: Actual data size written into file.
 * 
 * \return
 * 0 -- Success
 *  Nonzero -- Failure \see errno.h for possible values and their meaning
 */
int32_t AdkFs_Fwrite(adkfs_fhandle_t handle, const void *buf_ptr, size_t write_size, size_t *bytes_written);

/**
 * \brief Close a file
 * 
 * \param[in] handle: Handle to the file.
 * \return
 * 0 -- Success
 *  Nonzero -- Failure \see errno.h for possible values and their meaning
 */
int32_t AdkFs_Fclose(adkfs_fhandle_t *handle);

/**
 *  \brief Delete a file from the filesystem
 * 
 *  \param[in]  path: Absolute file path.
 *  \return
 *  0 -- Success
 *  Nonzero -- Failure \see errno.h for possible values and their meaning
 */
int32_t AdkFs_Fdelete(const char *path);

#endif /* ADKFS_H */

/*! @} */